<template>
  <el-dialog
    :close-on-click-modal="false"
    class="dia-style"
    :title="title"
    :visible.sync="open"
    width="1000px"
  >
    <hk-form
      ref="formRef"
      :data="form"
      :rules="rules"
      :label-width="labelWidth"
      :btn-hidden="btnHidden"
      :dict-list="dictList"
      :form-labels="formLabels"
      label-position="left"
      size="small"
     
    >
      <template #filter-appName>
        <el-select
          v-model="form.appName"
          clearable
          style="width: 100%"
          filterable
          :filter-method="dataFilter"
          @change="changeApp"
          @clear="dataFilter"
        >
          <el-option
            v-for="(item, index) in dictList.appList"
            :key="index"
            :label="item.name"
            :value="item.name"
          />
        </el-select>
      </template>
      <template #filter-inner>
        <div class="item-content">
          <div class="item">
            <div class="inline">
              <el-form-item label="地址:" label-width="60px" prop="inner.ip" :rules="rules.ipReg">
                <el-input v-model="form.inner.ip" @input="(val)=>getIP(form.inner)" />
              </el-form-item>
              <i>/</i>
              <span class="input-button">{{ form.inner.maskNum }}</span>
            </div>
            <div>
              <el-form-item
                label="掩码:"
                label-width="60px"
                :rules="{
                  required: true,
                  message: '请输入字段名称',
                  trigger: 'change',
                }"
              >
                <div class="inline">
                  <b>1</b>
                  <el-slider
                    v-model="form.inner.maskNum"
                    :min="1"
                    :max="32"
                    @input="(val)=>getIP(form.inner)"
                  />
                  <b>32</b>
                </div>
              </el-form-item>
            </div>
          </div>
          <div class="item">
            <el-form-item label="起始IP:" label-width="70px">
              <span class="input-button" style="width:auto">{{ form.inner.startIp }}</span>
            </el-form-item>
            <el-form-item label="结束IP:" label-width="70px">
              <span class="input-button" style="width:auto">{{ form.inner.endIp }}</span>
            </el-form-item>
            <el-form-item label="掩码:" label-width="70px">
              <span class="input-button" style="width:auto">{{ form.inner.mask }}</span>
            </el-form-item>
            <el-form-item>
              <div class="total-span">
                共计
                <span class="input-button">{{ form.inner.count }}</span> 个可用IP
              </div>
            </el-form-item>
          </div>
        </div>
      </template>
      <template #filter-outer>
        <div class="item-content">
          <div class="item">
            <div class="inline">
              <el-form-item label="地址:" label-width="60px" prop="outer.ip" :rules="rules.ipReg">
                <el-input v-model="form.outer.ip" @input="(val)=>getIP(form.outer)" />
              </el-form-item>
              <i>/</i>
              <span class="input-button">{{ form.outer.maskNum }}</span>
            </div>
            <div>
              <el-form-item
                label="掩码:"
                label-width="60px"
                :rules="{
                  required: true,
                  message: '请输入字段名称',
                  trigger: 'change',
                }"
              >
                <div class="inline">
                  <b>1</b>
                  <el-slider
                    v-model="form.outer.maskNum"
                    :min="1"
                    :max="32"
                    @input="(val)=>getIP(form.outer)"
                  />
                  <b>32</b>
                </div>
              </el-form-item>
            </div>
          </div>
          <div class="item">
            <el-form-item label="起始IP:" label-width="70px">
              <span class="input-button" style="width:auto">{{ form.outer.startIp }}</span>
            </el-form-item>
            <el-form-item label="结束IP:" label-width="70px">
              <span class="input-button" style="width:auto">{{ form.outer.endIp }}</span>
            </el-form-item>
            <el-form-item label="掩码:" label-width="70px">
              <span class="input-button" style="width:auto">{{ form.outer.mask }}</span>
            </el-form-item>
            <el-form-item>
              <div class="total-span">
                共计
                <span class="input-button">{{ form.outer.count }}</span> 个可用IP
              </div>
            </el-form-item>
          </div>
        </div>
      </template>
    </hk-form>
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @click="submitForm">保 存</el-button>
      <el-button @click="cancel">取 消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import HkForm from '@/components/Hk-Form'
import { getAppList, queryById, saveOrUpdate } from '@/api/approval/applicationAccess.js'

export default {
  components: { HkForm },
  props: {
    title: {
      type: String,
      default() {
        return '标题'
      }
    },
    keyword: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      // 是否显示弹出层
      open: false,
      // 标题宽度
      labelWidth: '150',
      // 是否显示按钮
      btnHidden: true,
      // 表单项配置
      formLabels: [
        {
          label: '应用系统',
          field: 'appName',
          list: 'appList',
          span: 24,
          type: 'slot'
        },
        {
          label: '应用部署服务器IP',
          field: 'serverIp',
          type: 'input',
          disabled: true
        },
        {
          label: '对外服务器端口',
          field: 'port',
          type: 'input',
          disabled: true
        },

        {
          label: '内部授权访问IP段',
          field: 'inner',
          type: 'slot',
          span: 24
        },
        {
          label: '外部授权访问IP段',
          field: 'outer',
          type: 'slot',
          span: 24
        }
      ],
      dictList: {
        appList: []
      },
      msgList: [],
      form: {
        inner: {},
        outer: { maskNum: 25 }
      },
      // 表单校验
      rules: {
        appName: [{ required: true, message: '不能为空', trigger: 'blur' }],
        serverIp: [{ required: true, message: '不能为空', trigger: 'blur' }],
        port: [{ required: true, message: '不能为空', trigger: 'blur' }],
        inner: [{ required: true, message: '不能为空', trigger: 'blur' }],
        ipReg: [
          { required: true, message: '请输入地址', trigger: 'blur' },
          {
            message: '地址格式不正确',
            trigger: 'blur',
            pattern: /^(?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))$/
          }
        ],
        outer: [{ required: true, message: '不能为空', trigger: 'blur' }]
      }
    }
  },

  created() {},
  methods: {
    // 打开页面
    show(id) {
      // this.$refs.formRef?.resetForm('formLabels')
      if (!this.msgList.length) {
        this.getMsgList()
      }
      if (!id) {
        this.reset()
        this.open = true
      } else {
        queryById(id).then(res => {
          this.form = res
          this.form.approvalTime=''
          this.form.inner.maskNum = res.innerMask
          this.form.outer.maskNum = res.outerMask
          this.$set(this.form.inner, 'ip', this.form.innerIp)
          this.$set(this.form.outer, 'ip', this.form.outerIp)
          // this.form.inner.ip = this.form.innerIp
          // this.form.outer.ip = this.form.outerIp
          this.open = true
        })
      }
    },
    // 获取应用系统列表信息
    getMsgList(val) {
      getAppList({ keyword: val }).then(res => {
        this.msgList = res
        this.dictList.appList = res
      })
    },
    // 筛选值
    dataFilter(val) {
      this.form.appName = val
      if (!val) {
        this.dictList.appList = this.msgList
        return
      }
      this.dictList.appList = this.msgList.filter(item => {
        return item.ip.includes(val) || item.name.includes(val)
      })
    },
    // 改变应用系统
    changeApp(val) {
      this.$forceUpdate()
      const item = this.dictList.appList.filter(item => item.name === val)
      this.form.serverIp = item[0]?.ip
      this.form.port = item[0]?.port
    },
    // 获取ip信息
    getIP(item) {
      this.$forceUpdate()
      const reg = /([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(\.([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])){3}$/
      if (!reg.test(item?.ip)) return
      item.count = Math.pow(2, 32 - item.maskNum) - 2 >= 0 ? Math.pow(2, 32 - item.maskNum) - 2 : 0
      const arr = Array(item.maskNum)
        .fill(1)
        .join('')
        .padEnd(32, '0')
        .replace(/(\d)(?=(?:\d{8})+$)/g, '$1,')
        .split(',')
      item.mask = arr.map(item => parseInt(item, 2)).join('.')
      item.startIp = this.calculateStartIP(item.ip, item.mask)
      item.endIp = this.calculateEndIP(item.startIp, item.mask)
    },
    // 计算开始ip
    calculateStartIP(ip, subnetMask) {
      const ipArr = ip.split('.')
      const maskArr = subnetMask.split('.')
      const startIPArr = []

      for (let i = 0; i < 4; i++) {
        startIPArr.push(ipArr[i] & maskArr[i])
      }

      return startIPArr.join('.')
    },
    // 计算结束ip
    calculateEndIP(startIp, subnetMask) {
      // 将IP地址和掩码转换为二进制形式
      const startIPBinary = startIp
        .split('.')
        .map(num =>
          parseInt(num)
            .toString(2)
            .padStart(8, '0')
        )
        .join('')
      const subnetMaskBinary = subnetMask
        .split('.')
        .map(num =>
          parseInt(num)
            .toString(2)
            .padStart(8, '0')
        )
        .join('')

      // 求掩码的反码
      const subnetMaskInverseBinary = subnetMaskBinary
        .split('')
        .map(bit => (bit == '0' ? '1' : '0'))
        .join('')

      // 计算结束IP地址的最后一位
      const endIPLastOctet = parseInt(startIPBinary.slice(-8), 2) | parseInt(subnetMaskInverseBinary.slice(-8), 2)

      // 将结束IP地址的最后一位替换到原IP地址并返回
      const endIPBinary = (parseInt(startIPBinary, 2) | parseInt(subnetMaskInverseBinary, 2)).toString(2).padStart(32, '0')

      const endIP = endIPBinary
        .match(/.{1,8}/g)
        .map(octet => parseInt(octet, 2))
        .join('.')

      return endIP
    },

    /** 提交按钮 */
    submitForm() {
      this.$refs.formRef.handleFormSubmit('formLabels').then(res => {
        this.form.innerIp = this.form.inner.ip
        this.form.outerIp = this.form.outer.ip
        this.form.innerMask = this.form.inner.maskNum
        this.form.outerMask = this.form.outer.maskNum
        this.form.innerIpRange = this.form.inner.ip + '/' + this.form.innerMask
        this.form.outerIpRange = this.form.outer.ip + '/' + this.form.outerMask
        if (this.form.id) {
          saveOrUpdate(this.form).then(response => {
            this.$modal.msgSuccess('修改成功')
            this.open = false
            this.$emit('handleSubmit')
          })
        } else {
          saveOrUpdate(res).then(response => {
            this.$modal.msgSuccess('新增成功')
            this.open = false
            this.$emit('handleSubmit')
          })
        }
      })
    },
    // 取消按钮
    cancel() {
      this.open = false
      this.reset()
    },
    // 表单重置
    reset() {
      this.form = {
        appName: '',
        serverIp: '',
        port: '',
        inner: {
          ip: '',
          startIp: '',
          endIp: '',
          mask: '',
          count: undefined,
          maskNum: 0
        },
        outer: {
          ip: '',
          startIp: '',
          endIp: '',
          mask: '',
          count: undefined,
          maskNum: 0
        }
      }
      this.$refs.formRef?.resetForm('formLabels')
    }
  }
}
</script>

<style lang="scss" scoped>
.item-content {
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 4px;
  display: flex;
  align-items: stretch;
  .item {
    padding: 20px;
    width: 50%;
    .el-form-item {
      margin-bottom: 0;
    }
    .inline {
      display: flex;
      align-items: center;
      margin-bottom: 10px;
      & > i {
        margin: 0 10px;
        font-size: 20px;
      }
      & > b {
        font-style: normal;
        font-size: 14px;
        color: #4b6eef;
        font-weight: 400;
      }
    }
    & + .item {
      border-left: 2px solid rgba(0, 0, 0, 0.05);
    }
  }
}
.total-span {
  display: flex;
  align-items: center;
  .input-button {
    margin: 0 10px;
  }
}
.input-button {
  font-style: normal;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 90px;
  height: 32px;
  color: #4b6eef;
  background: #f6f8fe;
  border: 1px solid rgba(75, 110, 239, 0.6);
  border-radius: 4px;
}
.el-form-item + .el-form-item {
  margin-top: 10px;
}
.el-slider {
  flex: 1;
  margin: 0 10px 0 20px;
}
::v-deep {
  .el-dialog__body {
    height: 620px !important;
  }
}
#app.dark-theme{
  .input-button{
    background: transparent;
    color: #fff;
  }
}
</style>
